<!DOCTYPE html>
<html>
<head>
<title>Thermodynamics Chain Diagram</title>
</head>
<body>
<canvas id="physicsCanvas" width="800" height="450"></canvas>
<script>
    const canvas = document.getElementById('physicsCanvas');
    const ctx = canvas.getContext('2d');

    // Background
    ctx.fillStyle = 'white';
    ctx.fillRect(0, 0, canvas.width, canvas.height);

    // Drawing styles
    ctx.strokeStyle = 'black';
    ctx.lineWidth = 2.5;
    ctx.lineCap = 'round';
    ctx.lineJoin = 'round';

    // --- Chain Drawing ---

    const y_chain = 150;
    const h_radiusX = 35;
    const h_radiusY = 14;
    const v_radiusX = 14;
    const v_radiusY = 40;

    // Function to draw a horizontal ellipse
    function drawHorizontal(x, y) {
        ctx.beginPath();
        ctx.ellipse(x + h_radiusX, y, h_radiusX, h_radiusY, 0, 0, 2 * Math.PI);
        ctx.stroke();
        return 2 * h_radiusX; // width
    }

    // Function to draw a vertical ellipse
    function drawVertical(x, y) {
        ctx.beginPath();
        ctx.ellipse(x + v_radiusX, y, v_radiusX, v_radiusY, 0, 0, 2 * Math.PI);
        ctx.stroke();
        return 2 * v_radiusX; // width
    }

    // Function to draw a connection dot
    function drawDot(x, y, color = 'black') {
        ctx.fillStyle = color;
        ctx.beginPath();
        ctx.arc(x, y, 3, 0, 2 * Math.PI);
        ctx.fill();
    }
    
    // The sequence of segments in the diagram, visually matched
    const sequence = ['H', 'H', 'V', 'H', 'H', 'V', 'V', 'H', 'V', 'H', 'H'];
    const total_width = sequence.reduce((sum, type) => sum + (type === 'H' ? 2 * h_radiusX : 2 * v_radiusX), 0);
    let currentX = (canvas.width - total_width) / 2;
    const startX = currentX;

    // Draw the segments and connection points
    sequence.forEach((type, index) => {
        let width;
        if (type === 'H') {
            width = drawHorizontal(currentX, y_chain);
        } else { // type === 'V'
            width = drawVertical(currentX, y_chain);
        }
        
        currentX += width;

        // Draw connection dot after the current segment (at the connection point)
        if (index < sequence.length - 1) {
            // The first connection dot is green as seen in the provided crop
            const dotColor = (index === 0) ? '#006400' : 'black'; // DarkGreen or black
            drawDot(currentX, y_chain, dotColor);
        }
    });

    const endX = currentX;

    // --- Arrow and Labels ---

    // Arrow
    const y_arrow = 250;
    const arrowHeadSize = 15;
    ctx.beginPath();
    ctx.moveTo(startX, y_arrow);
    ctx.lineTo(endX, y_arrow);
    // Arrowhead
    ctx.moveTo(endX, y_arrow);
    ctx.lineTo(endX - arrowHeadSize, y_arrow - arrowHeadSize * 0.6);
    ctx.moveTo(endX, y_arrow);
    ctx.lineTo(endX - arrowHeadSize, y_arrow + arrowHeadSize * 0.6);
    ctx.stroke();

    // Text "nx"
    ctx.fillStyle = 'black';
    ctx.font = 'italic 28px "Times New Roman"';
    ctx.textAlign = 'center';
    ctx.fillText('nx', canvas.width / 2, y_arrow + 45);

    // Text "Fig. 2.4."
    ctx.font = '28px "Times New Roman"';
    ctx.fillText('Fig. 2.4.', canvas.width / 2, y_arrow + 100);

</script>
</body>
</html>